package com.mjf.cjt.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import com.alibaba.fastjson2.JSONObject;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.chanjet.openapi.sdk.java.exception.ChanjetApiException;
import com.mjf.cjt.domain.VoucherIncome;
import com.mjf.cjt.mapper.VoucherIncomeMapper;
import com.mjf.cjt.service.AsyncTMService;
import com.mjf.cjt.service.VoucherIncomeService;
import com.mjf.cjt.vo.ExpenseVoucherCreateVO;
import com.mjf.cjt.vo.TFResultVO;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * <p>
 * desc
 * </p>
 *
 * @author chenshoumeng
 * @date 2025/7/16 13:47
 */
@Slf4j
@Service
public class VoucherIncomeServiceImpl extends ServiceImpl<VoucherIncomeMapper, VoucherIncome>
    implements VoucherIncomeService
{

    @Autowired
    private AsyncTMService asyncTMService;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void pushExpenseVoucher(String start, String end) {
        // 查询未推送的T+费用单

        List<VoucherIncome> list = list(Wrappers.<VoucherIncome>lambdaQuery().eq(VoucherIncome::getIsPush, 0)
            .ge(VoucherIncome::getCreateTime, start)
            .le(VoucherIncome::getCreateTime, end));
        if (CollectionUtil.isNotEmpty( list)) {
            for (VoucherIncome income : list) {
//                income.setVoucherDate(LocalDate.now());
                income.setTimes(LocalDateTime.now());
                // 按外部单据号分组
                Map<String, List<VoucherIncome>> map = list.stream().collect(Collectors.groupingBy(VoucherIncome::getExternalCode));
                for (Map.Entry<String, List<VoucherIncome>> entry : map.entrySet()) {
                    ExpenseVoucherCreateVO vo = new ExpenseVoucherCreateVO();
                    vo.setVoucherDate(entry.getValue().get(0).getVoucherDate().format(DateTimeFormatter.ofPattern("yyyy-MM-dd")));
                    vo.setExternalCode(entry.getValue().get(0).getExternalCode());
                    ExpenseVoucherCreateVO.BusinessTypeVO businessTypeVO = new ExpenseVoucherCreateVO.BusinessTypeVO();
                    businessTypeVO.setCode(entry.getValue().get(0).getBusinessTypeCode());
                    vo.setBusinessType(businessTypeVO);
                    ExpenseVoucherCreateVO.BillTypeVO billTypeVO = new ExpenseVoucherCreateVO.BillTypeVO();
                    billTypeVO.setCode(entry.getValue().get(0).getBillTypeCode());
                    vo.setBillType(billTypeVO);
                    ExpenseVoucherCreateVO.PartnerVO partnerVO = new ExpenseVoucherCreateVO.PartnerVO();
                    partnerVO.setCode(entry.getValue().get(0).getCode());
                    vo.setPartner(partnerVO);
                    List<ExpenseVoucherCreateVO.DetailVO> details = new ArrayList<>();
                    for (VoucherIncome detail : entry.getValue()) {
                        ExpenseVoucherCreateVO.DetailVO detailVO = new ExpenseVoucherCreateVO.DetailVO();
                        detailVO.setExpenseitemCode(detail.getExpenseitemCode());
                        detailVO.setTaxRate(detail.getTaxRate());
                        detailVO.setOrigAmount(detail.getOrigAmount());
                        detailVO.setOrigTax(detail.getOrigTax());
                        detailVO.setOrigTaxAmount(detail.getOrigTaxAmount());
                        detailVO.setExpenseItemUse(detail.getExpenseItemUse());
                        details.add(detailVO);
                    }
                    vo.setDetails(details);
                    try {
                        TFResultVO result = asyncTMService.pushExpenseVoucher(vo);
                        if ("0".equals(result.getCode())) {
                            income.setIsPush(1);
                        }
                        income.setPushResult(JSONObject.toJSONString(result));
                    } catch (ChanjetApiException e) {
                        log.error("推送异常 {}", income);
                        income.setPushResult(e.getMessage());
                    }
                }
            }
            updateBatchById(list);
        }
    }
}
